/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2008-2014, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.data.wfs; import static org.geotools.data.wfs.internal.Loggers.*; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.geotools.data.Diff; import org.geotools.data.FeatureReader; import org.geotools.data.store.ContentState; import org.geotools.geometry.jts.ReferencedEnvelope; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.Name; import org.opengis.filter.Filter; import org.opengis.geometry.BoundingBox; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; public class WFSDiff extends Diff { public static class BatchUpdate { final Name[] properties; final Object[] values; final Filter filter; public BatchUpdate(Name[] properties, Object[] values, Filter filter) { this.properties = properties; this.values = values; this.filter = filter; } } // record batch modified fids so a single update element is not built for them by // WFSRemoteTransactionState private Set<String> batchModified; private List<BatchUpdate> batchCommands; public WFSDiff() { super(); batchModified = new HashSet<String>(); batchCommands = new ArrayList<WFSDiff.BatchUpdate>(); } @Override public synchronized void clear() { batchModified.clear(); batchCommands.clear(); super.clear(); } public List<BatchUpdate> getBatchUpdates() { return batchCommands; } public Set<String> getBatchModified() { return batchModified; } @Override public void modify(String fid, SimpleFeature f) { synchronized (batchModified) { boolean removed = batchModified.remove(fid); if (removed) { // will cause an extra update to be sent after the batch modifications MODULE.finer("Removing " + fid + " from list of batch modified features as it's being modified directly"); } } super.modify(fid, f); } public ReferencedEnvelope batchModify(Name[] properties, Object[] values, Filter filter, FeatureReader<SimpleFeatureType, SimpleFeature> oldFeatures, ContentState contentState) throws IOException { ReferencedEnvelope bounds = new ReferencedEnvelope(contentState.getFeatureType() .getCoordinateReferenceSystem()); synchronized (batchModified) { while (oldFeatures.hasNext()) { SimpleFeature old = oldFeatures.next(); BoundingBox fbounds = old.getBounds(); if (fbounds != null) { bounds.expandToInclude(new ReferencedEnvelope(fbounds)); } for (int i = 0; i < properties.length; i++) { Name propName = properties[i]; Object newValue = values[i]; old.setAttribute(propName, newValue); if (newValue instanceof Geometry) { Envelope envelope = ((Geometry) newValue).getEnvelopeInternal(); bounds.expandToInclude(envelope); } } String fid = old.getID(); super.modify(fid, old); batchModified.add(fid); } BatchUpdate batch = new BatchUpdate(properties, values, filter); batchCommands.add(batch); } return bounds; } }